package com.qihetimes.earthangel.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qihetimes.earthangel.common.ApiException;
import com.qihetimes.earthangel.common.MessageType;
import com.qihetimes.earthangel.mapper.FriendRelationMapper;
import com.qihetimes.earthangel.model.FriendRelation;
import com.qihetimes.earthangel.model.User;
import com.qihetimes.earthangel.model.vo.PageVO;
import com.qihetimes.earthangel.model.vo.UserVO;
import com.qihetimes.earthangel.service.IConversationService;
import com.qihetimes.earthangel.service.IFriendRelationService;
import com.qihetimes.earthangel.service.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 好友关系表 服务实现类
 * </p>
 *
 * @author f4cklangzi@gmail.com
 * @since 2021-12-11
 */
@Service
public class FriendRelationServiceImpl extends ServiceImpl<FriendRelationMapper, FriendRelation> implements IFriendRelationService {
    
    @Resource
    private IUserService userService;
    
    @Resource
    private IConversationService conversationService;
    
    @Override
    public PageVO<UserVO> getFriendList(String userId, Long pageNum, Long pageSize) {
        Page<FriendRelation> queryPage = new Page<>(pageNum, pageSize);
        lambdaQuery().and(
            query -> query
                .eq(FriendRelation::getFromUserId, userId)
                .or()
                .eq(FriendRelation::getToUserId, userId)
        )
            .page(queryPage);
        PageVO<UserVO> page = new PageVO<>(queryPage);
        if (queryPage.getRecords().isEmpty()) {
            return page;
        }
        List<String> friendIdList = queryPage.getRecords().stream().map(friendRelation -> {
            if (userId.equals(friendRelation.getFromUserId())) {
                return friendRelation.getToUserId();
            } else {
                return friendRelation.getFromUserId();
            }
        }).collect(Collectors.toList());
        List<UserVO> friendList = userService.lambdaQuery()
            .in(User::getId, friendIdList).orderByAsc(User::getNickName)
            .list().stream().map(user -> {
                UserVO userVO = BeanUtil.toBean(user, UserVO.class);
                userVO.setFriendFlag(true);
                return userVO;
            }).collect(Collectors.toList());
        page.setRecords(friendList);
        return page;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(String userId) {
        User loginUser = userService.getLoginUser();
        User user = userService.getById(userId);
        if (user == null) {
            throw new ApiException("用户不存在!");
        }
        Integer count = lambdaQuery().and(query -> {
            query.eq(FriendRelation::getFromUserId, loginUser.getId())
                .eq(FriendRelation::getToUserId, userId);
        }).or(query -> {
            query.eq(FriendRelation::getToUserId, loginUser.getId())
                .eq(FriendRelation::getFromUserId, userId);
        }).count();
        if (count > 0) {
            throw new ApiException("请勿重复添加!");
        }
        FriendRelation friendRelation = new FriendRelation();
        friendRelation.setId(IdUtil.objectId());
        friendRelation.setFromUserId(loginUser.getId());
        friendRelation.setToUserId(userId);
        friendRelation.setCreatedAt(LocalDateTime.now());
        save(friendRelation);
        JSONObject object = new JSONObject();
        object.set("userId", loginUser.getId());
        object.set("nickName", loginUser.getNickName());
        object.set("avatarUrl", loginUser.getAvatarUrl());
        String content = JSONUtil.toJsonStr(object);
        conversationService.sendSystemMessage(MessageType.FRIEND_ADD, user, content, true);
    }
    
    @Override
    public void delete(String userId) {
        User loginUser = userService.getLoginUser();
        lambdaUpdate()
            .and(query -> {
                query.eq(FriendRelation::getFromUserId, loginUser.getId())
                    .eq(FriendRelation::getToUserId, userId);
            })
            .or(query -> {
                query.eq(FriendRelation::getToUserId, loginUser.getId())
                    .eq(FriendRelation::getFromUserId, userId);
            })
            .remove();
    }
}
